package com.gitee.wsl.common.chart.sample.scatter

import android.graphics.Canvas
import android.graphics.Paint
import com.gitee.wsl.common.chart.ChartEnum
import com.gitee.wsl.common.chart.adapter.DataSource
import com.gitee.wsl.common.chart.adapter.SelectItemChartAdapter
import com.gitee.wsl.common.chart.listener.click.PlotPointPosition
import com.gitee.wsl.common.chart.render.background.axis.line.CategoryLineAxis
import com.gitee.wsl.common.chart.render.background.axis.line.DataLineAxis
import com.gitee.wsl.common.chart.render.background.quadrant.Quadrant
import com.gitee.wsl.common.chart.render.shape.plot.renderDot
import com.gitee.wsl.common.chart.sample.line.AbstractLineChart
import com.gitee.wsl.common.chart.sample.scatter.adapter.ScatterChartAdapter
import com.gitee.wsl.common.chart.sample.scatter.model.ScatterData
import com.gitee.wsl.common.ui.draw.type.DotStyle
import com.gitee.wsl.android.ui.ext.type.drawRotateText
import com.gitee.wsl.transform.format.Format
import timber.log.Timber

/**
 * @ClassName ScatterChart
 * @Description  散点图基类
 * @author XiongChuanLiang<br/>(xcl_168@aliyun.com)
 *
 */

class ScatterChart(val adapter: ScatterChartAdapter = ScatterChartAdapter()):AbstractLineChart(adapter),
    SelectItemChartAdapter<ScatterData> by adapter {

    //数据源
    var dataset by DataSource(adapter)

    //分类轴的最大，最小值
    var maxValue = 0.0f
    var minValue = 0.0f

    //用于格式化标签的回调接口
    var labelFormatter: Format<String>? = null

    //用于绘制点的画笔
    val pointPaint: Paint by lazy{
        Paint(Paint.ANTI_ALIAS_FLAG)
    }

    //四象限类
    val plotQuadrant: Quadrant = Quadrant()

    init {
        this.isAxesClosed=true
    }

    override fun getType(): ChartEnum.ChartType {
        return ChartEnum.ChartType.SCATTER
    }

    override fun categoryAxisDefaultSetting(categoryAxis: CategoryLineAxis) {
        super.categoryAxisDefaultSetting(categoryAxis)
        categoryAxis.tickMarksAlign=Paint.Align.CENTER
    }

     override fun dataAxisDefaultSetting(dataAxis: DataLineAxis) {
         super.dataAxisDefaultSetting(dataAxis)
         dataAxis.tickMarksAlign=Paint.Align.LEFT
    }


    /**
     * 绘制象限
     * @param canvas 画布
     */
    private fun drawQuadrant(canvas: Canvas,dataAxis: DataLineAxis) {
        if (!plotQuadrant.isVisible) return

        //float axisScreenWidth = getPlotScreenWidth(); 
        //float axisScreenHeight = getPlotScreenHeight();
        //float axisDataHeight = dataAxis.getAxisRange(); 	
        val xValue: Float = plotQuadrant.quadrantXValue
        val yValue: Float = plotQuadrant.quadrantYValue

        //对应的Y坐标
        //float centerY = (float) (axisScreenHeight * ( (yValue - dataAxis.getAxisMin() ) / axisDataHeight)) ;  

        //对应的X坐标	  	  
        //float centerX = (float) (axisScreenWidth * ( (xValue - mMinValue ) / (mMaxValue - mMinValue))) ;  
        val centerX = getLnXValPosition(xValue, maxValue, minValue)
        val centerY = getVPValPosition(yValue,dataAxis)
        plotQuadrant.renderQuadrant(
            canvas, centerX, centerY,
            bodyViewport.left, bodyViewport.top, bodyViewport.right, bodyViewport.bottom
        )
    }


    private fun drawPoints(canvas: Canvas, bd: ScatterData, dataID: Int, dataAxis: DataLineAxis) {
        if (maxValue.compareTo(minValue) == -1) {
            Timber.d( "轴最大值小于最小值.")
            return
        }
        if (maxValue.compareTo(minValue) == 0) {
            Timber.d( "轴最大值与最小值相等.")
            return
        }
        val axisDataHeight: Float = dataAxis.axisRange
        if (axisDataHeight.compareTo(0.0f) == 0 || axisDataHeight.compareTo(0.0f) == -1) {
            Timber.d( "数据轴高度小于或等于0.")
            return
        }

        //得到标签对应的值数据集		
        val chartValues = bd.pointMap

        //画出数据集对应的线条				
        var YvaluePos = 0.0f
        var XvaluePos = 0.0f
        val itemAngle = bd.itemLabelRotateAngle
        val dot = bd.plotDot
        val radius = dot.dotRadius
        val count = chartValues.size
        for (i in 0 until count) {
            val entry = chartValues[i]
            XvaluePos = getLnXValPosition(entry.x, maxValue, minValue)
            YvaluePos = getVPValPosition(entry.y,dataAxis)
            if (dot.dotStyle != DotStyle.HIDE) {
                pointPaint.color = dot.color
                pointPaint.alpha = dot.alpha
                canvas.renderDot(
                     dot, XvaluePos, YvaluePos, pointPaint
                )
                savePointRecord(
                    dataID, i, XvaluePos + moveX, YvaluePos + moveY,
                    XvaluePos - radius + moveX, YvaluePos - radius + moveY,
                    XvaluePos + radius + moveX, YvaluePos + radius + moveY
                )
            }

            //显示批注形状
            drawAnchor(anchorSet, dataID, i, canvas, XvaluePos, YvaluePos, radius)
            if (bd.isLabelVisible) {
                //请自行在回调函数中处理显示格式
                canvas.drawRotateText(
                    labelFormatter?.invoke("${entry.x},${entry.y}")?:"${entry.x},${entry.y}",
                    XvaluePos, YvaluePos, itemAngle,
                     bd.labelPaint
                )
            }
        }
        adapter.isRecordSetInited = true
    }

    /**
     * 绘制图
     */
    private fun drawPlot(canvas: Canvas, dataAxis: DataLineAxis): Boolean {
        //检查是否有设置分类轴的最大最小值		
        if (maxValue == minValue && 0.0f == maxValue) {
            Timber.d( "请检查是否有设置分类轴的最大最小值。")
            return false
        }

        //绘制四象限
        drawQuadrant(canvas,dataAxis)

        //开始处 X 轴 即分类轴              	
        val count = dataset.size
        for (i in 0 until count) {
            val bd = dataset[i]
            if (bd.plotDot.dotStyle == DotStyle.HIDE && !bd.isLabelVisible) {
                continue
            }
            drawPoints(canvas, bd, i,dataAxis)
        }
        return true
    }

    /////////////////////////////////////////////
    override fun drawClipPlot(canvas: Canvas, dataAxis: DataLineAxis, categoryAxis: CategoryLineAxis) {
        if (drawPlot(canvas,dataAxis)) {
            //画横向定制线
            if (null != customLine) {
                customLine!!.setVerticalPlot(dataAxis, bodyViewport, getAxisScreenHeight())
                customLine!!.renderVerticalCustomlinesDataAxis(canvas)
            }
        }
    }

    fun savePointRecord(
        dataID: Int, childID: Int,
        x: Float, y: Float, left: Float, top: Float, right: Float, bottom: Float
    ) {
        if(adapter.isRecordSetInited) return
        val pRecord = PlotPointPosition()
        pRecord.savePlotDataID(dataID)
        pRecord.savePlotDataChildID(childID)
        pRecord.savePlotPosition(x, y)
        pRecord.savePlotRectF(left, top, right, bottom)
        //pRecord.extPointClickRange(clickRangeExtValue)
        adapter.addRecordItem(pRecord)
    }

     override fun drawClipLegend(canvas: Canvas) {
        //图例
        //plotLegend.renderPointKey(canvas, mDataset)
    }
    /////////////////////////////////////////////
}